contents
๐ณ ์ฝ๋ฉ ํ ์คํธ๋ฅผ ์ํ ๊ทธ๋ํ & ํธ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ โ ์ฌ์ธต ๊ฐ์ด๋์ ์์
1. ๊ทธ๋ํ(Graph) ์๊ณ ๋ฆฌ์ฆ
a. ๊ธฐ๋ณธ ๊ฐ๋
- ๊ทธ๋ํ(Graph) ๋ ์ ์ (Vertex) ๊ณผ ๊ฐ์ (Edge) ์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
- ๊ทธ๋ํ ์ ํ:
- ๋ฐฉํฅ ๊ทธ๋ํ(Directed): ๊ฐ์ ์ ๋ฐฉํฅ ์กด์ฌ
- ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ(Undirected)
- ๊ฐ์ค์น ๊ทธ๋ํ(Weighted) / ๋น๊ฐ์ค์น ๊ทธ๋ํ(Unweighted)
- ์ ํฅ/๋ฌดํฅ, ์ฐ๊ฒฐ/๋น์ฐ๊ฒฐ
- ์ฌ์ดํด ์กด์ฌ(Cyclic) / ๋ฌด์ฌ์ดํด(Acyclic)
b. ํต์ฌ ๊ทธ๋ํ ์ํ(Traversal) ์๊ณ ๋ฆฌ์ฆ
DFS (Depth-First Search, ๊น์ด ์ฐ์ ํ์)
- ๊ฐ๋ฅํ ํ ๊น์ด ๋ค์ด๊ฐ๋ค๊ฐ, ๋ ์ด์ ์งํํ ์ ์์ผ๋ฉด ๋๋์์ค๋ ๋ฐฉ์
- ์คํ(Stack) ๋๋ ์ฌ๊ท(Recursion) ์ฌ์ฉ
- ํ์ฉ: ์ฌ์ดํด ํ์ง, ์ฐ๊ฒฐ ์์ ํ์, DAG์์ ์์ ์ ๋ ฌ, ๋ฏธ๋ก ํ์
void dfs(int node, boolean[] visited, List<Integer>[] adj) {
visited[node] = true;
for (int next : adj[node]) {
if (!visited[next]) dfs(next, visited, adj);
}
}
BFS (Breadth-First Search, ๋๋น ์ฐ์ ํ์)
- ์ธ์ ํ ๋ ธ๋๋ฅผ ๋จผ์ ๋ชจ๋ ๋ฐฉ๋ฌธํ ํ, ๊ทธ ๋ค์ ๋ ๋ฒจ๋ก ์งํ
- ํ(Queue) ์ฌ์ฉ
- ํ์ฉ: ๋น๊ฐ์ค์น ๊ทธ๋ํ ์ต๋จ๊ฒฝ๋ก, ๋ ๋ฒจ ํ์, ์ด๋ถ ๊ทธ๋ํ ํ๋ณ
void bfs(int start, List<Integer>[] adj, boolean[] visited) {
Queue<Integer> queue = new LinkedList<>();
queue.add(start);
visited[start] = true;
while (!queue.isEmpty()) {
int node = queue.poll();
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
queue.add(neighbor);
}
}
}
}
๋ค์ต์คํธ๋ผ(Dijkstra) ์๊ณ ๋ฆฌ์ฆ
- ๊ฐ์ค์น๊ฐ ๋ชจ๋ ์์์ธ ๊ทธ๋ํ์์ ํ๋์ ์์์ ์ผ๋ก๋ถํฐ ๋ชจ๋ ์ ์ ๊น์ง์ ์ต๋จ๊ฑฐ๋ฆฌ ๊ณ์ฐ
- ์ฐ์ ์์ ํ(PriorityQueue) ์ฌ์ฉ
PriorityQueue<Pair> pq = new PriorityQueue<>((a, b) -> a.dist - b.dist);
pq.add(new Pair(source, 0));
while (!pq.isEmpty()) {
Pair p = pq.poll();
// ์ธ์ ํ ๋
ธ๋ ๊ฒ์ฌ ํ, ๋ ์งง์ ๊ฒฝ๋ก ๋ฐ๊ฒฌ ์ ๊ฐฑ์ ๋ฐ pq์ ์ถ๊ฐ
}
๊ทธ ์ธ ์ค์ํ ๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ
- ์์ ์ ๋ ฌ(Topological Sort) โ ๋ฐฉํฅ์ฑ ๋น์ํ ๊ทธ๋ํ(DAG)์์ ์์ ๊ฒฐ์
- ์ ๋์จ ํ์ธ๋(Union-Find, Disjoint Set) โ ์งํฉ ๋ณํฉ/์ฌ์ดํด ํ์ง
- ์ต์ ์ ์ฅ ํธ๋ฆฌ(MST) โ Kruskal / Prim ์๊ณ ๋ฆฌ์ฆ (๋ชจ๋ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ๋ ์ต์ ๋น์ฉ)
2. ํธ๋ฆฌ(Tree) ์๊ณ ๋ฆฌ์ฆ
a. ๊ธฐ๋ณธ ๊ฐ๋
- ํธ๋ฆฌ(Tree): ์ฌ์ดํด์ด ์๋ ๊ณ์ธต์ ์๋ฃ ๊ตฌ์กฐ
- **๋ฃจํธ ๋ ธ๋(Root)**์ ์์ ๋ ธ๋(Children) ๊ตฌ์ฑ
- ์ด์ง ํธ๋ฆฌ(Binary Tree): ๊ฐ ๋ ธ๋๊ฐ ์ต๋ 2๊ฐ์ ์์(Left/Right)์ ๊ฐ์ง
- ์ด์ง ํ์ ํธ๋ฆฌ(BST): ์ผ์ชฝ < ๋ถ๋ชจ < ์ค๋ฅธ์ชฝ ์์ ์ ์ง
b. ํธ๋ฆฌ ์ํ ๋ฐฉ๋ฒ
์ค์(Inorder), ์ ์(Preorder), ํ์(Postorder) ์ํ
- Inorder (LNR): ์ผ์ชฝ โ ๋ ธ๋ โ ์ค๋ฅธ์ชฝ (BST ํ์ ์ ์ค๋ฆ์ฐจ์)
- Preorder (NLR): ๋ ธ๋ โ ์ผ์ชฝ โ ์ค๋ฅธ์ชฝ
- Postorder (LRN): ์ผ์ชฝ โ ์ค๋ฅธ์ชฝ โ ๋ ธ๋
void inorder(TreeNode root) {
if (root == null) return;
inorder(root.left);
System.out.print(root.val + " ");
inorder(root.right);
}
๋ ๋ฒจ ์์ ์ํ(Level Order, BFS)
- ๋ฃจํธ๋ถํฐ ์์ํด ๊ฐ์ ๋ ๋ฒจ์ ๋ ธ๋๋ค์ ์ฐจ๋ก๋๋ก ๋ฐฉ๋ฌธ
void levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
System.out.print(node.val + " ");
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
}
์์ฃผ ์ฐ์ด๋ ํธ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ
- ์ต์ ๊ณตํต ์กฐ์(LCA, Lowest Common Ancestor)
- ํธ๋ฆฌ ๊ท ํํ(AVL, Red-Black Tree)
- ํ(Heap) โ ์ฐ์ ์์ ํ ๊ตฌํ, ํ ์ ๋ ฌ
3. ์ฝ๋ฉ ํ ์คํธ์์ ์์ฃผ ๋์ค๋ ๋ฌธ์ ์์
๊ทธ๋ํ(Graph):
- ๋ ๋ ธ๋ ๊ฐ ๋ชจ๋ ๊ฒฝ๋ก ์ฐพ๊ธฐ (DFS/๋ฐฑํธ๋ํน)
- ์ต๋จ ๊ฒฝ๋ก (BFS/๋ค์ต์คํธ๋ผ)
- ์ฌ์ดํด ๊ฐ์ง (DFS/์ ๋์จ ํ์ธ๋)
- ์์ ์ ๋ ฌ (BFS/DFS)
ํธ๋ฆฌ(Tree):
- ์ด์ง ํธ๋ฆฌ ๋ค์ง๊ธฐ
- BST ๊ฒ์ฆ
- LCA ์ฐพ๊ธฐ
- ํธ๋ฆฌ ์ต๋ ๊ฒฝ๋ก ํฉ
- ํธ๋ฆฌ ์ง๋ ฌํ/์ญ์ง๋ ฌํ
4. ์์ฝ ํ
| ์นดํ ๊ณ ๋ฆฌ | ์๊ณ ๋ฆฌ์ฆ | ์๋ฃ๊ตฌ์กฐ | ํ์ฉ ์ฌ๋ก |
|---|---|---|---|
| ๊ทธ๋ํ | DFS/BFS | ๋ฆฌ์คํธ/ํ/์คํ | ํ์, ๊ฒ์, ์ต๋จ ๊ฑฐ๋ฆฌ |
| ๊ทธ๋ํ | ๋ค์ต์คํธ๋ผ/MST | ์ฐ์ ์์ ํ, DSU | ๊ฐ์ค์น ์ต๋จ ๊ฒฝ๋ก, ์ต์ ๋น์ฉ ์ฐ๊ฒฐ |
| ํธ๋ฆฌ | ์ค์/์ ์/ํ์ ์ํ | ์ฌ๊ท/์คํ | ์ ๋ ฌ, ์์ ๊ธฐ๋ฐ ํ์ |
| ํธ๋ฆฌ | LCA, BST ์ฐ์ฐ | ํธ๋ฆฌ ๋ ธ๋ | ์กฐ์ ํ์, ๊ฒ์/์ฝ์ /์ญ์ |
๐ก Tip:
- DFS/BFS๋ ๊ทธ๋ํ ํ์ + ํธ๋ฆฌ ์ํ ๋ฌธ์ ๋ชจ๋์์ ์์ฃผ ๋ฑ์ฅํ๋ ๋ฐ๋ณต ์์ง
- ํธ๋ฆฌ ๋ฌธ์ ์์๋ ์ฌ๊ท ํจํด ์ดํด, ๊ทธ๋ํ ๋ฌธ์ ์์๋ ํ/์คํ ์๋ฃ๊ตฌ์กฐ ์ฌ์ฉ๋ฒ ์์ง ํ์
- ์ฐ๊ฒฐ/๋น์ฐ๊ฒฐ ๊ทธ๋ํ ๋ชจ๋ ๊ณ ๋ ค, ์ฌ์ดํด ์ฌ๋ถ ์ฒดํฌ ์ต๊ดํ
๐ ๊ทธ๋ํ(Graph) ๋ํ ์ถ์ ๋ฌธ์
1. ์ต๋จ ๊ฒฝ๋ก ์ฐพ๊ธฐ
- BFS: ๋น๊ฐ์ค์น ๊ทธ๋ํ์์ ์์์ โ ๋ชจ๋ ๋
ธ๋๊น์ง ์ต๋จ ๊ฑฐ๋ฆฌ
- (์: ๋ฏธ๋ก ๋ฌธ์ , ๋คํธ์ํฌ hop ์)
- Dijkstra: ๊ฐ์ค์น(์์) ๊ทธ๋ํ์์ ์์์ โ ์ต์ ๋น์ฉ
- (์: ์ง๋ ๊ฒฝ๋ก, ์์ ๋คํธ์ํฌ ์ต์ ์ฐ๊ฒฐ)
2. ์ฌ์ดํด ๊ฐ์ง
- DFS + ๋ฐฉ๋ฌธ ๋ฐฐ์ด
- ๋ฌด๋ฐฉํฅ/๋ฐฉํฅ ๊ทธ๋ํ ๋ชจ๋
- (์: ์ปค๋ฅ์ ๋ฃจํ ์ฒดํฌ, ์ํ ์ฐธ์กฐ ๊ฒ์ถ)
- Union Find(Disjoint Set)
- ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ ์ฌ์ดํด ๋น ๋ฅธ ๊ฒ์ถ
3. ์ต์ ์ ์ฅ ํธ๋ฆฌ(MST)
- Kruskal/ Prim ์๊ณ ๋ฆฌ์ฆ
- ๋ชจ๋ ๋ ธ๋ ์ฐ๊ฒฐ ์ต์ ๋น์ฉ
- (์: ํต์ ๋ง ๊ตฌ์ถ ๋น์ฉ, ๋์ ๋๋ก๋ง ์ฐ๊ฒฐ)
4. ์์ ์ ๋ ฌ(Topological Sort)
- ๋ฐฉํฅ์ฑ ๋น์ํ ๊ทธ๋ํ(DAG)์์ ์์ ์ ํ๊ธฐ
- (์: ์์ ์์, ์๊ฐ ๊ณผ๋ชฉ/ํ๋ก์ ํธ ์ ํ๊ด๊ณ)
5. ๋ชจ๋ ๊ฒฝ๋ก/๋๋ฌ ์ฌ๋ถ ์ฐพ๊ธฐ
- DFS/BFS ํ์ฉ
- ๋ ๋ ธ๋ ์ฌ์ด์ ๋ชจ๋ ๊ฒฝ๋ก, ๋จ์ผ ๊ฒฝ๋ก, ์ต๋ ๊ฒฝ๋ก ๋ฑ
- (์: ํธ๋ฆฌ ๋ถ๊ธฐ ๊ฒฝ๋ก, ๊ทธ๋ํ ์ฐ๊ฒฐ์ฑ ํ์ธ)
6. ๊ทธ๋ํ ์ฐ๊ฒฐ ์์ ๊ฐ์
- DFS/BFS๋ก ๋ฐฉ๋ฌธ ์ ๋ ๋
ธ๋ ๊ทธ๋ฃน ์นด์ดํธ
- (์: ์ฌ ๊ฐ์, ๋คํธ์ํฌ ์ปดํฌ๋ํธ)
๐ณ ํธ๋ฆฌ(Tree) ๋ํ ์ถ์ ๋ฌธ์
1. ํธ๋ฆฌ ์ํ(Traversal)
- ์ค์/์ ์/ํ์ (์ฌ๊ท/๋ฐ๋ณต)
- (์: ์ด์ง ํธ๋ฆฌ ์ถ๋ ฅ, ๋ ธ๋ ํ์ ๋ฑ)
2. ํธ๋ฆฌ ์ต๋/์ต์ ๊ฒฝ๋ก ํฉ
- DFS๋ก ๋ชจ๋ ๋ฃจํธ-๋ฆฌํ ๊ฒฝ๋ก ํ์
- (์: ํธ๋ฆฌ์ ์ต๋/์ต์ sum ๊ฒฝ๋ก)
3. BST ๊ฒ์ฆ/๊ตฌ์ฑ
- ์ด์ง ํ์ ํธ๋ฆฌ(BST)์ธ์ง ์ฒดํฌ, BST ์์ฑ/์ฝ์
/์ญ์
- (์: ํธ๋ฆฌ๋ก ์ ๋ ฌ, ํธ๋ฆฌ ๊ฒ์ ์ต์ ํ)
4. ํธ๋ฆฌ ๋ค์ง๊ธฐ/๋ฆฌ๋ฒ์ค
- ํธ๋ฆฌ ๊ตฌ์กฐ ์ข์ฐ ๋ฐ์ (๊ฑฐ์ธ ํธ๋ฆฌ)
- (์: LeetCode 226)
5. ์ต์ ๊ณตํต ์กฐ์(LCA) ์ฐพ๊ธฐ
- ๋ ๋
ธ๋์ ๊ฐ์ฅ ์๋(๊ณตํต) ์กฐ์ ์ฐพ๊ธฐ
- (์: ๋ฆฌ๋ ์ค ๊ฒฝ๋ก, ๊ถํ ํธ๋ฆฌ)
6. ํธ๋ฆฌ ์ง๋ ฌํ/์ญ์ง๋ ฌํ
- ํธ๋ฆฌ/๊ทธ๋ํ๋ฅผ ์คํธ๋ง(๋ฆฌ์คํธ ๋ฑ)์ผ๋ก ๋ณํ/๋ณต์
- (์: JSON/XML ๊ตฌ์กฐ ๋ณํ, ๋ฐ์ดํฐ ์ ์ฅ)
โ ์์ฝ ํ
| ๊ทธ๋ํ ๋ฌธ์ | ๋ํ ์๊ณ ๋ฆฌ์ฆ/ํจํด | ํธ๋ฆฌ ๋ฌธ์ | ๋ํ ์๊ณ ๋ฆฌ์ฆ/ํจํด |
|---|---|---|---|
| ์ต๋จ ๊ฒฝ๋ก(BFS/Dijkstra) | BFS, Dijkstra, Queue | ํธ๋ฆฌ ์ํ(Traversal) | ์ฌ๊ท, Stack/Queue |
| ์ฌ์ดํด ๊ฐ์ง | DFS, Union Find | ์ต๋ ๊ฒฝ๋ก ํฉ | DFS, ๋์ ํฉ |
| MST (์ต์ ์ ์ฅ ํธ๋ฆฌ) | Kruskal, Prim, ์ฐ์ ์์ ํ | BST ๊ฒ์ฆ/์ฝ์ /์ญ์ | ์ฌ๊ท |
| ์์ ์ ๋ ฌ | DFS, BFS + Queue | ํธ๋ฆฌ ๋ฆฌ๋ฒ์ค/๋ค์ง๊ธฐ | DFS, Swap |
| ๋ชจ๋ ๊ฒฝ๋ก/์ฐ๊ฒฐ ์์ | DFS, BFS, ์ปดํฌ๋ํธ ๊ตฌ๋ณ | LCA(์ต์ ๊ณตํต ์กฐ์) | DFS, ๊ฒฝ๋ก ๊ธฐ๋ก |
| ๊ทธ๋ํ ์ง๋ ฌํ/์ญ์ง๋ ฌํ | BFS/DFS, Encoding/Decoding | ์ง๋ ฌํ/์ญ์ง๋ ฌํ | BFS/DFS, LevelOrder |
๐ก ์ค์ ํ
- BFS/DFS ์ ์ ๊ตฌํ์ ๋ฐ๋์ ์๊ธฐ ๋ฐ ์์ฝ๋ฉ ์ฐ์ต!
- ๊ทธ๋ํ ์ ๋ ฅ(์ธ์ ํ๋ ฌ vs ์ธ์ ๋ฆฌ์คํธ), ํธ๋ฆฌ ๋ ธ๋ ๊ตฌ์กฐ์ ์น์ํด์ ธ์ผ ํจ
- ํธ๋ฆฌ/๊ทธ๋ํ ๋ฌธ์ ๋ชจ๋ ์๋ฃ๊ตฌ์กฐ์ ์๊ณ ๋ฆฌ์ฆ ์ ํ์ด ๊ด๊ฑด
- ๋ฐ๋ก ๋ง๋ค๋ฉฐ ํ ์คํธ! (๋น์ฐ๊ฒฐ, ์ฌ์ดํด, ๋น ํธ๋ฆฌ, ๊ฒฝ๋ก ์์ ๋ฑ)
references